package com.rpay.service.user.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mysql.jdbc.log.LogUtils;
import com.rpay.common.dto.user.UserDTO;
import com.rpay.common.util.LoggerUtil;
import com.rpay.common.util.common.CommonUtils;
import com.rpay.common.vo.PcsResult;
import com.rpay.dao.user.UserDao;
import com.rpay.model.user.UserDO;
import com.rpay.service.config.ServiceThreadLocal;
import com.rpay.service.user.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Title：
 * Description
 *
 * @author fxg06 on 2018/4/20
 * @version 1.0
 */
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserDao userDao;

    @Override
    public UserDTO getUserByAccount(String account) {
        UserDO userDO = userDao.selectUser(account);
        UserDTO user = convertDOToDTO(userDO);
        return user;
    }

    @Override
    public boolean saveUser(UserDTO userDTO) {
        UserDO userDO = convertDTOToDO(userDTO);
        userDao.insert(userDO);
        return true;
    }

    @Override
    public boolean updateUser(UserDTO userDTO) {
        UserDO userDO = convertDTOToDO(userDTO);
        userDao.update(userDO);
        return true;
    }

    @Override
    public UserDTO getUserById(Integer userId) {
        UserDO userDO = userDao.selectById(userId);
        return convertDOToDTO(userDO);
    }

    @Override
    public UserDTO getUserByShareCode(String shareCode) {
        UserDO userDO = userDao.selectByShareCode(shareCode);
        return convertDOToDTO(userDO);
    }

    @Override
    public List<UserDTO> getAllUser(String teamKey) {
        List<UserDO> list = userDao.selectAll(teamKey);
        List<UserDTO> userList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(list)) {
            for (UserDO userDO : list) {
                userList.add(convertDOToDTO(userDO));
            }
        }
        return userList;
    }

    @Override
    public List<UserDTO> getAllUserByRootUser(UserDTO rootUser) {
        List<UserDO> list = userDao.selectAllByRootUserId(rootUser.getId());
        List<UserDTO> userList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(list)) {
            for (UserDO userDO : list) {
                userList.add(convertDOToDTO(userDO));
            }
        }
        return userList;
    }

    private static int deepLevel = 0;


    /**
     * 获取代数
     *
     * @param userDTO
     * @return
     */
    private int getDeep(UserDTO userDTO, List<UserDTO> userDTOList) {
        if (!CollectionUtils.isEmpty(userDTOList)) {
            return getMaxDeep(userDTO, userDTOList);
        } else {
            return 1;
        }

    }

    private int getMaxDeep(UserDTO userDTO, List<UserDTO> userDTOList) {
        int maxNum = 0;
        for (UserDTO user : userDTOList) {
            if (userDTO.getParentId().equals(user.getId())) {
                maxNum = 1 + getDeep(user, userDTOList);
            }

        }
        return maxNum;
    }

    /**
     * 迭代生成树结构数据
     *
     * @param userDTO
     * @param allList
     * @return
     */
    private Map getChild(UserDTO userDTO, List<UserDTO> allList) {
        Map<String, Object> map = Maps.newHashMap();


        map.put("key", userDTO.getId().toString());
        map.put("level", userDTO.getLevel());
        List<Map> mapList = Lists.newArrayList();
        int count = 0;
        if (!CollectionUtils.isEmpty(allList)) {
            for (UserDTO user : allList) {
                if (user.getParentId().equals(userDTO.getId())) {
                    count++;
                    Map childObj = getChild(user, allList);
                    mapList.add(childObj);
                }
            }
        }
        int totalCount = this.getTotalCount(userDTO, allList);
        map.put("count", count);
        map.put("totalCount", totalCount);

        int deep = this.getDeep(userDTO, allList);

        String title = userDTO.getName() + "|" + userDTO.getEmail() + "|" + userDTO.getPhone() + " [" +
                "" + deep + "][" + count + "][" + userDTO.getLevel() + "][" + totalCount + "]";
        map.put("title", title);
        map.put("level", userDTO.getLevel());
        map.put("name", userDTO.getName());
        map.put("email", userDTO.getEmail());
        map.put("phone", userDTO.getPhone());

        map.put("children", mapList);
        return map;
    }

    private int getCount(UserDTO userDTO, List<UserDTO> allList) {
        int count = 0;
        for (UserDTO user : allList) {
            if (user.getParentId().equals(userDTO.getId())) {
                count++;
            }
        }
        return count;
    }


    /**
     * 获取伞下团队人数
     *
     * @param userDTO
     * @param allUserDTOList
     * @return
     */
    private int getTotalCount(UserDTO userDTO, List<UserDTO> allUserDTOList) {

        if (!CollectionUtils.isEmpty(allUserDTOList)) {
            return getMaxCount(userDTO, allUserDTOList);
        } else {
            return 0;
        }
    }

    /**
     * 递归计算
     *
     * @param userDTO
     * @param allUserDTOList
     * @return
     */
    private int getMaxCount(UserDTO userDTO, List<UserDTO> allUserDTOList) {
        int totalCount = this.getCount(userDTO, allUserDTOList);
        for (UserDTO user : allUserDTOList) {
            if (user.getParentId().equals(userDTO.getId())) {
                totalCount = totalCount + getMaxCount(user, allUserDTOList);
            }
        }
        return totalCount;
    }


    /**
     * 根据keyword 查询用户
     * allList 参数 为了计算直推数量和代数
     *
     * @param keyword
     * @return
     */
//    public List<Map> findUserListByKeyword(String keyword) {
    public Map findUserListByKeyword(String keyword) {
        Map param = new HashMap();
        // 去掉keyword条件
        param.put("keyword", keyword);
        // 根据关键词查询用户列表
        List<UserDO> userDOList = userDao.selectUsersByKeyword(param);
        List<UserDTO> userDTOList = Lists.newArrayList();
        // 查询所有的用户 用来计算代数和直推人数
        List<UserDO> allUserDOList = userDao.selectAll(null);
        List<UserDTO> allUserDTOList = Lists.newArrayList();

        List<Map> result = new ArrayList();


        if (!CollectionUtils.isEmpty(userDOList)) {
            for (UserDO userDO : userDOList) {
                userDTOList.add(convertDOToDTO(userDO));
            }
        }

        if (!CollectionUtils.isEmpty(allUserDOList)) {
            for (UserDO userDO : allUserDOList) {
                allUserDTOList.add(convertDOToDTO(userDO));
            }
        }

        return this.buildTree(userDTOList, allUserDTOList);

    }

    @Override
    public boolean upgrade(Integer userId) {
        UserDO user = userDao.selectUserById(userId);
        if (user == null) {
            return false;
        }
        List<UserDO> upgradeList = Lists.newArrayList();
        List<UserDO> list = userDao.selectUsers(user.getTeamKey());
        boolean flag = isUpgrade(user, list);
        if (flag) {
            //每次只能升一级
            user.setLevel(user.getLevel() + 1);
            upgradeList.add(user);
            upgradeList = getUpgradeUserList(user, list, upgradeList);
            userDao.upgrade(upgradeList);
        }
        return true;
    }

    @Override
    public List<UserDTO> listUserByParentId(Integer parentId) {
        List<UserDTO> userDTOList = Lists.newArrayList();
        List<UserDO> list = userDao.selectByParentId(parentId);
        if (!CollectionUtils.isEmpty(list)) {
            for (UserDO userDO : list) {
                userDTOList.add(convertDOToDTO(userDO));
            }
        }
        return userDTOList;
    }

    private UserDTO convertDOToDTO(UserDO userDO) {
        UserDTO userDTO = null;
        if (userDO != null) {
            userDTO = new UserDTO();
            userDTO.setId(userDO.getId());
            userDTO.setEmail(userDO.getEmail());
            userDTO.setName(userDO.getName());
            userDTO.setUsername(userDO.getUsername());
            userDTO.setPhone(userDO.getPhone());
            userDTO.setPassword(userDO.getPassword());
            userDTO.setSecretKey(userDO.getSecretKey());
            userDTO.setShareCode(userDO.getShareCode());
            userDTO.setTeamKey(userDO.getTeamKey());
            userDTO.setParentId(userDO.getParentId());
            userDTO.setLevel(userDO.getLevel());
            userDTO.setTradePassword(userDO.getTradePassword());
            userDTO.setRippleAmount(userDO.getRippleAmount());
            userDTO.setRpayAmount(userDO.getRpayAmount());
            userDTO.setBuyAmount(userDO.getBuyAmount());
            userDTO.setStatus(userDO.getStatus());
        }
        return userDTO;
    }

    private UserDO convertDTOToDO(UserDTO userDTO) {
        UserDO userDO = null;
        if (userDTO != null) {
            userDO = new UserDO();
            if (userDTO.getId() != null) {
                userDO.setId(userDTO.getId());
            }
            userDO.setParentId(userDTO.getParentId());
            userDO.setEmail(userDTO.getEmail());
            userDO.setPassword(userDTO.getPassword());
            userDO.setName(userDTO.getName());
            userDO.setPhone(userDTO.getPhone());
            userDO.setSecretKey(userDTO.getSecretKey());
            userDO.setTradePassword(userDTO.getTradePassword());
            userDO.setShareCode(userDTO.getShareCode());
            userDO.setTeamKey(userDTO.getTeamKey());
            userDO.setRippleAmount(userDTO.getRippleAmount());
            userDO.setRpayAmount(userDTO.getRpayAmount());
            userDO.setBuyAmount(userDTO.getBuyAmount());
        }
        return userDO;
    }

    private List<UserDO> getUpgradeUserList(UserDO user, List<UserDO> list, List<UserDO> upgradeList) {
        if (!CollectionUtils.isEmpty(list)) {
            for (UserDO userDO : list) {
                if (userDO.getId().equals(user.getParentId())) {
                    boolean flag = isUpgrade(userDO, list);
                    if (flag) {
                        upgradeList.add(userDO);
                        getUpgradeUserList(userDO, list, upgradeList);
                        break;
                    }
                }
            }
        }
        return upgradeList;
    }

    private boolean isUpgrade(UserDO user, List<UserDO> list) {
        boolean flag = false;
        if (!CollectionUtils.isEmpty(list)) {
            for (UserDO userDO : list) {
                if (user.getId().equals(userDO.getId())) {
                    if (user.getLevel() == 0 && user.getInvestAmount().doubleValue() >= 100) {
                        userDO.setLevel(1);
                        flag = true;
                    } else {
                        int count = getChildUserCount(user.getId(), user.getLevel(), list);
                        if (user.getLevel() == 1 && user.getInvestAmount().doubleValue() >= 1000) {
                            //满足两个子级的用户等级大于大于1级，可升级
                            if (count >= 2) {
                                userDO.setLevel(2);
                                flag = true;
                            }
                        } else if (user.getLevel() == 2 && user.getInvestAmount().doubleValue() >= 3000) {
                            //满足两个子级的用户等级大于大于2级，可升级
                            if (count >= 2) {
                                userDO.setLevel(3);
                                flag = true;
                            }
                        } else if (user.getLevel() == 3 && user.getInvestAmount().doubleValue() >= 5000) {
                            //满足两个子级的用户等级大于大于3级，可升级
                            if (count >= 2) {
                                userDO.setLevel(4);
                                flag = true;
                            }
                        } else if (user.getLevel() == 4 && user.getInvestAmount().doubleValue() >= 10000) {
                            //满足两个子级的用户等级大于大于4级，可升级
                            if (count >= 2) {
                                userDO.setLevel(5);
                                flag = true;
                            }
                        } else if (user.getLevel() == 5 && user.getInvestAmount().doubleValue() >= 20000) {
                            //满足三个子级的用户等级大于大于5级，可升级
                            if (count >= 3) {
                                //获取用户团队下充值总金额
                                BigDecimal sumBigDecimal = getChildInvestAmount(user.getId(), list);
                                BigDecimal tempBigDecimal = new BigDecimal(2000000);
                                //团队充值数量大于或等于2000000
                                if (sumBigDecimal.compareTo(tempBigDecimal) != -1) {
                                    userDO.setLevel(6);
                                    flag = true;
                                }
                            }
                        }
                    }
                    break;
                }
            }
        }
        return flag;
    }

    private int getChildUserCount(Integer userId, Integer userLevel, List<UserDO> list) {
        int count = 0;
        if (!CollectionUtils.isEmpty(list)) {
            for (UserDO user : list) {
                //当用户的父id为该用户id时，且他的用户等级大于或等于该用户等级 count+1
                if (user.getParentId().equals(userId) && user.getLevel() >= userLevel) {
                    count++;
                }
            }
        }
        return count;
    }

    private BigDecimal getChildInvestAmount(Integer userId, List<UserDO> list) {
        BigDecimal sumBigDecimal = BigDecimal.ZERO;
        if (!CollectionUtils.isEmpty(list)) {
            for (UserDO user : list) {
                //当用户的父id为该用户id时，且他的用户等级大于或等于该用户等级 count+1
                if (user.getParentId().equals(userId)) {
                    sumBigDecimal = sumBigDecimal.add(user.getInvestAmount());
                    //递归查询所有子级
                    sumBigDecimal = sumBigDecimal.add(getChildInvestAmount(user.getId(), list));
                }
            }
        }
        return sumBigDecimal;
    }

    public static void main(String[] args) {
        System.out.println((1200 * 4.3846 + 900 * 4.3944 + 100 * 4.3813 + 200 * 4.3901) * 0.05 / 7);
    }


    /**
     * 树结构工具
     */

    /**
     * 判断是否为根节点
     *
     * @return
     */
    private boolean isRootNode(UserDTO userDTO, List<UserDTO> userDTOList) {
        boolean isRootNode = true;
        for (UserDTO node : userDTOList) {

            if (userDTO.getParentId().equals(node.getId())) {

                isRootNode = false;

                break;

            }

        }
        return isRootNode;
    }

    /**
     * 获取集合中所有的根节点
     *
     * @param nodes
     * @return
     */

    public List<UserDTO> getRootNodes(List<UserDTO> nodes) {
        List<UserDTO> rootNodes = new ArrayList<UserDTO>();
        for (UserDTO n : nodes) {
            if (isRootNode(n, nodes)) {
                rootNodes.add(n);
            }
        }
        return rootNodes;
    }


    /**
     * 获取父节点下所有的子节点
     *
     * @param pNode
     * @param nodes
     * @return
     */

    public List<UserDTO> getChildNodes(UserDTO pNode, List<UserDTO> nodes) {
        List<UserDTO> childNodes = new ArrayList<UserDTO>();
        for (UserDTO n : nodes) {
            if (pNode.getId().equals(n.getParentId())) {
                childNodes.add(n);
            }
        }
        return childNodes;
    }

    /**
     * 递归子节点
     * 测试方法 等待删除
     *
     * @param node
     */

    public Map buildChildNodes(UserDTO node, List<UserDTO> nodes) {

//        List<UserDTO> children = getChildNodes(node,nodes);
//
//        if (!children.isEmpty()) {
//
//            for(UserDTO child : children) {
//
//                buildChildNodes(child ,nodes);
//
//            }
//
//            node.setMenus(children);
//
//        }
//


        Map<String, Object> map = Maps.newHashMap();


        map.put("key", node.getId().toString());
        map.put("parentKey", node.getParentId().toString());
        map.put("level", node.getLevel());
        List<Map> mapList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(nodes)) {
            for (UserDTO user : nodes) {
                if (user.getParentId().equals(node.getId())) {
                    Map childObj = buildChildNodes(user, nodes);
                    mapList.add(childObj);
                }
            }
            String title = node.getEmail();
            map.put("title", title);
            map.put("children", mapList);
        }


        return map;


    }


    //    public List<Map> buildTree(List<UserDTO> userDTOList, List<UserDTO> allUserDTOList) {
    public Map buildTree(List<UserDTO> userDTOList, List<UserDTO> allUserDTOList) {

        List<Map> treeNodes = new ArrayList<Map>();

        List<UserDTO> rootNodes = getRootNodes(userDTOList);

        for (UserDTO rootNode : rootNodes) {
//            buildChildNodes(rootNode,userDTOList)
            treeNodes.add(getChild(rootNode, allUserDTOList));

        }
        Map resultMap = new HashMap();
        resultMap.put("treeData", treeNodes);
        resultMap.put("treeDataList", builTreeDataList(userDTOList));
        return resultMap;

    }

    public List<Map> builTreeDataList(List<UserDTO> userDTOList) {
        List<Map> resultList = new ArrayList<Map>();
        for (UserDTO userDTO : userDTOList) {
            Map map = new HashMap();
            String title = userDTO.getName() + "|" + userDTO.getEmail() + "|" + userDTO.getPhone();
            map.put("key", userDTO.getId().toString());
            map.put("parentKey", userDTO.getParentId().toString());
            map.put("title", title);
            resultList.add(map);
        }
        return resultList;
    }


}
